﻿#ifndef FFMPEG_H
#define FFMPEG_H

#include <mutex>
#include <QString>

extern "C" {
#include "libavformat/avformat.h"
#include "libavformat/version.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
}

namespace HeaderMedia {

class FFmpeg {
 public:
  static FFmpeg &getInstance() {
    static FFmpeg f;
    return f;
  }

  bool open(const QString &videoPath);
  int decode(const AVPacket *pkt);

  AVPacket read(bool &ok);

  bool yuvToRGB(char *out, int outWidth, int outHeight);

  int toPCM(char *out);
  void close();
  bool seek(float pos);
  int getPts(const AVPacket *pkt);

  int totalMs() const {
    return xTotalMs;
  }

  int sampleRate() const {
    return xSampleRate;
  }

  int sampleSize() const {
    return xSampleSize;
  }

  int channel() const {
    return xChannel;
  }

  void setPlayStatus(const bool &status) {
    xIsPlay = status;
  }

  int pts() const {
    return xPts;
  }

  bool isPlay() const {
    return xIsPlay;
  }

  int audioStream() const {
    return xAudioStream;
  }

  int videoStream() const {
    return xVideoStream;
  }

 private:
  FFmpeg();

  bool openCodec(AVCodecContext *acc);

  bool xIsPlay;
  // 视频帧数据
  AVFrame *xYUV = nullptr;
  // 音频数据
  AVFrame *xPCM = nullptr;
  // 转换器
  SwsContext *xSws = nullptr;

  int xSampleRate = 48000;
  int xSampleSize = 16;
  int xChannel = 2;
  int xVideoStream = 0;
  int xAudioStream = 1;
  // 当前视频播放进度
  int xPts;
  int xTotalMs;

  AVFormatContext *xAVForContext = nullptr;
  // 音频
  SwrContext *xSwrContext = nullptr;
  std::mutex xMtx;
};

} // HeaderMedia

#endif // FFMPEG_H
